import * as config from "config";
import {Types} from "mongoose";
import {InstanceType} from "typegoose";
import GM from "../../database/models/gm";
import {KickbackRecordModel} from "../../database/models/kickbackRecord";
import {PaymentOrderModel} from "../../database/models/paymentOrder";
import {Player, PlayerModel} from "../../database/models/player";
import {Recharge} from "../../database/models/recharge";
import {RechargeOrder, RechargeOrderModel} from "../../database/models/rechargeOrder";
import {wechatPayAuther} from "../../wechat/wechatCashier";
import {expect, requestToApiServer, setupTestEnv, tearDownTestEnv, XMLbuilder} from "./helper";

describe('充值', () => {

  let player: InstanceType<Player> = null
  let playerPoor: InstanceType<Player> = null
  let recharge: InstanceType<Recharge> = null
  let jwt: string = null
  let jwtPoor: string = null

  before(async () => {
    const env = await setupTestEnv()

    player = env.player
    playerPoor = env.playerPoor
    recharge = env.recharge
    jwt = env.jwt
    jwtPoor = env.jwtPoor
  })

  after(() => {
    return tearDownTestEnv()
  })

  context('获取', () => {
    it('获取充值列表', () => {

      return requestToApiServer()
        .get('/recharge')
        .set({'x-jwt': jwt})
        .then(({body}) => {
          expect(body).to.have.properties({
            ok: true, data: {}
          })
          expect(body.data.recharge[0]._id).to.equal(recharge.id)
        })
    })

    it('获取一个充值信息', () => {

      return requestToApiServer()
        .get(`/recharge/${recharge.id}`)
        .then(({body}) => {
          expect(body).to.have.properties({
            ok: true, data: {
              recharge: {_id: recharge.id}
            }
          })
        })
    })
  })

  context('微信', async () => {

    it('微信充值', async () => {

      await requestToApiServer()
        .post(`/rechargeorder/${recharge.id}`)
        .set({'x-jwt': jwt})
        .send({
          payType: 'wechatPay'
        })
        .expect(200)

      await requestToApiServer()
        .post(`/rechargeorder/${recharge.id}`)
        .set({'x-jwt': jwtPoor})
        .send({
          payType: 'wechatPay'
        })
        .expect(200)
    })

    it('确认付款', async () => {
      const gmBefo = await GM.findOne({role: `super`}).lean()
      const gm1Befo = await GM.findOne({role: `level1`}).lean()
      const gm2Befo = await GM.findOne({role: `level2`}).lean()

      let rechargeOrder: InstanceType<RechargeOrder> = null

      await requestToApiServer()
        .post(`/rechargeorder/${recharge.id}`)
        .set({'x-jwt': jwt})
        .send({
          payType: 'wechatPay'
        })
        .expect(200)
        .then(({body}) => {
          rechargeOrder = body.data.rechargeOrder
        })

      const payOrder = await PaymentOrderModel.findOne({
        orderType: 'RechargeOrder', order: rechargeOrder._id
      })

      const notification = {
        out_trade_no: payOrder.id,
        result_code: 'SUCCESS', return_code: 'SUCCESS',
      }
      const sign = wechatPayAuther.sign(notification)

      const xml = XMLbuilder.buildObject({...notification, sign})

      const res = await requestToApiServer()
        .post('/wechatpay/notify')
        .type('xml')
        .send(xml)
        .expect(200)
        .then((res) => {
          expect(res.text).to.equal('<xml><return_code><![CDATA[SUCCESS]]></return_code></xml>')
        })

      expect(await PaymentOrderModel.findOne({
        orderType: 'RechargeOrder', order: rechargeOrder._id
      })).to.have.properties({state: 'finished'})

      expect(await RechargeOrderModel.findById(rechargeOrder._id).lean())
        .to.have.properties({state: 'paid'})

      const p: InstanceType<Player> = await PlayerModel.findById(player)
      expect(p.coin).to.equal(player.coin + recharge.coin)
      expect(p.freeCoin).to.equal(player.freeCoin + recharge.freeCoin)
      expect(p.gem).to.equal(player.gem + recharge.gem)

      const RMBCost = payOrder.price
      const pKickback = config.get<number>('kickback.coin.playerToGmKickback')
      const gmKickback = config.get<number>('kickback.coin.gmToGmKickback')

      const gm = await GM.findOne({role: `super`}).lean()
      const gm1 = await GM.findOne({role: `level1`}).lean()
      const gm2 = await GM.findOne({role: `level2`}).lean()
      expect(gm2.cashKickback - gm2Befo.cashKickback).to.equal(RMBCost * pKickback)
      expect(gm1.cashKickback - gm1Befo.cashKickback).to.equal(RMBCost * pKickback * gmKickback)
      expect(gm.cashKickback - gmBefo.cashKickback).to.equal(RMBCost * pKickback * (1 + gmKickback))

      const kickbackRecord = await KickbackRecordModel.findOne({fromId: Types.ObjectId(rechargeOrder._id)})
      expect(kickbackRecord.kickback2).to.equal(RMBCost * pKickback)
      expect(kickbackRecord.kickback1).to.equal(RMBCost * pKickback * gmKickback)
      expect(kickbackRecord.kickbackAll).to.equal(RMBCost * pKickback * (1 + gmKickback))
    })
  })

  context('支付宝', () => {

    it('支付宝充值', () => {

      return requestToApiServer()
        .post(`/rechargeorder/${recharge.id}`)
        .set({'x-jwt': jwt})
        .send({
          payType: 'aliPay'
        })
        .expect(200)
    })
  })
})
